package com.lechi.web.listener;

import com.lechi.web.common.config.LeChiConfig;
import com.lechi.web.common.utils.DateUtils;
import com.lechi.web.framework.log.IotExceptionLog;
import com.lechi.web.service.IIotFtpUploadsService;
import com.lechi.web.service.IIotSensorRecordService;
import com.lechi.web.system.domain.IotFtpUploads;
import com.lechi.web.system.domain.IotSensorRecordBo;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.contentobjects.jnotify.JNotify;
import net.contentobjects.jnotify.JNotifyAdapter;
import net.contentobjects.jnotify.JNotifyException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.Date;
import java.util.concurrent.CompletableFuture;


/**
 * The type Jnotify adapter.
 */
@Slf4j
@Component
public class FileJnotifyAdapter extends JNotifyAdapter {

    /**
     * ftp目录监听程序Id
     */
    public int ftpWatchID;

    /**
     * 传感器目录监听程序Id
     */
    public int recordWatchID;
    /**
     * 关注目录的事件
     */
    int mask = JNotify.FILE_CREATED | JNotify.FILE_DELETED;
    /**
     * 是否监视子目录，即级联监视
     */
    boolean watchSubtree = true;

    @Getter
    @Value("${ftp.watch.path}")
    private String uploadPath;

    @Getter
    @Value("${ftp.watch.timeout}")
    private Long timeout;

    @Autowired
    private IIotFtpUploadsService iotFtpUploadsService;

    @Autowired
    private IIotSensorRecordService iIotSensorRecordService;

    /**
     * 容器启动时启动监视程序
     */
    public void beginWatch() {
        try {
            this.ftpWatchID = JNotify.addWatch(uploadPath, mask, watchSubtree, this);
            this.recordWatchID = JNotify.addWatch(LeChiConfig.getRecordLogPath(), mask, watchSubtree, this);
            log.info("FileJnotifyAdapter -----------启动成功-----------");
        } catch (JNotifyException e) {
            log.error("FileJnotifyAdapter beginWatch", e);
        }
        /**
         * 死循环，线程一直执行，休眠一分钟后继续执行，主要是为了让主线程一直执行 休眠时间和监测文件发生的效率无
         * （就是说不是监视目录文件改变一分钟后才监测到，监测几乎是实时的，调用本地系统库）
         */
        while (true) {
            try {
                Thread.sleep(timeout);
            } catch (InterruptedException e) {// ignore it
            }
        }
    }

    /**
     * 文件创建
     *
     * @param watchID  监听程序Id 初始为1，多个监控程序以此加1
     * @param rootPath 目录名
     * @param name     文件名
     */

    @Override
    public void fileCreated(int watchID, String rootPath, String name) {
        String filePath = rootPath + File.separator + name;
        log.info(watchID + "----->文件被创建, 创建位置为： " + filePath);
        String separator = File.separator;
        String[] stirs = name.split(separator);
        if (watchID == ftpWatchID) {
            IotFtpUploads iotFtpUploads = new IotFtpUploads();
            try {
                iotFtpUploads.setDeviceStation(stirs[0]);
                iotFtpUploads.setFilepath(filePath);
                iotFtpUploads.setFilename(name);
                String dateTime = name.substring(name.lastIndexOf(stirs[1]), name.lastIndexOf("."));
                Date createTime = DateUtils.parseDate(dateTime, DateUtils.YYYYMMDDHHMMSS);
                iotFtpUploads.setCreateTime(createTime);
                iotFtpUploadsService.insertIotFtpUploads(iotFtpUploads);
            } catch (Exception e) {
                StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[1];
                String method = Thread.currentThread().getName() + ":" + stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName();
                CompletableFuture.runAsync(IotExceptionLog.exceptionLog(e, "Ftp文件notify监听服务异常", method, iotFtpUploads));
            }
        }
        if (watchID == recordWatchID) {
            IotSensorRecordBo IotSensorRecordBo = new IotSensorRecordBo();
            try {
                IotSensorRecordBo.setFilepath(filePath);
                IotSensorRecordBo.setFilename(name);
                String dateTime = name.substring(name.lastIndexOf("_") + 1, name.lastIndexOf("."));
                Date createTime = DateUtils.parseDate(dateTime, DateUtils.YYYYMMDDHHMMSS);
                IotSensorRecordBo.setDeviceId(Long.parseLong(stirs[0]));
                IotSensorRecordBo.setCreateTime(createTime);
                iIotSensorRecordService.insertIotSensorRecord(IotSensorRecordBo);
            } catch (Exception e) {
                StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[1];
                String method = Thread.currentThread().getName() + ":" + stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName();
                CompletableFuture.runAsync(IotExceptionLog.exceptionLog(e, "传感器要素文件notify监听服务异常", method, IotSensorRecordBo));
            }
        }
    }
}
